﻿using Nasty.Core.Session;
using Nasty.Core.Entity;
using SqlSugar;
using Nasty.Core.Entity.System;
using Nasty.Core.Attributes;
using Nasty.Core.SuperExtension;
using Nasty.Core.Registry;

namespace Nasty.Core.Entity.Flow
{
    [SugarTable("SysFlow", TableDescription = "流程")]
    public class Flow : StandardEntity<Flow>
    {
        /// <summary>
        /// 名称
        /// </summary>
        [NastyColumn(ColumnName = "Name", IsOnlyIgnoreUpdate = true, ColumnDescription = "名称", Required = true)]
        public string? Name { get; set; }

        /// <summary>
        /// 流程配置Id
        /// </summary>
        [NastyColumn(ColumnName = "FlowConfigId", IsOnlyIgnoreUpdate = true, ColumnDescription = "流程配置Id", Required = true)]
        public string? FlowConfigId { get; set; }

        /// <summary>
        /// 流程触发器
        /// </summary>
        [NastyColumn(ColumnName = "FlowAction", IsOnlyIgnoreUpdate = true, ColumnDescription = "流程触发器")]
        public string? FlowAction { get; set; }

        /// <summary>
        /// 通知触发器
        /// </summary>
        [NastyColumn(ColumnName = "NoticeAction", IsOnlyIgnoreUpdate = true, ColumnDescription = "通知触发器")]
        public string? NoticeAction { get; set; }

        /// <summary>
        /// 当前节点Id
        /// </summary>
        [NastyColumn(ColumnName = "CurrentNodeId", ColumnDescription = "当前节点Id")]
        public string? CurrentNodeId { get; set; }


        [Navigate(NavigateType.OneToOne, nameof(Flow.CurrentNodeId), nameof(Flow.CurrentNode.Id))]
        public FlowNode CurrentNode { get; set; }


        /// <summary>
        /// 当前节点Code
        /// </summary>
        [NastyColumn(IsIgnore = true)]
        public string? CurrentNodeCode
        {
            get
            {
                return CurrentNode?.Code ?? string.Empty;
            }
        }

        /// <summary>
        /// 当前审批人Ids
        /// </summary>
        [NastyColumn(ColumnName = "CurrentApproverIds", IsJson = true, ColumnDescription = "当前审批人Ids", ColumnDataType = StaticConfig.CodeFirst_BigString)]
        public List<string> CurrentApproverIds { get; set; }

        /// <summary>
        /// 是否结束
        /// </summary>
        [NastyColumn(ColumnName = "IsEnd", ColumnDescription = "是否结束")]
        public bool IsEnd { get; set; }


        public override void OnPreAdd()
        {
            base.OnPreAdd();

            var db = AppSession.CurrentDb.Value;

            var config = db.Queryable<Nasty.Core.Entity.Flow.FlowConfig>().InSingle(this.FlowConfigId);
            if (config == null) throw new Exception("流程配置不存在");
            if (!config.IsPublish) throw new Exception("流程配置未发布");
            if (string.IsNullOrEmpty(config.FlowAction)) throw new Exception("流程配置触发器不能为空");

            this.FlowAction = config.FlowAction;
            this.NoticeAction = config.NoticeAction;

            var firstNode = db.Queryable<FlowConfigNode>()
                .Where((t) => t.FlowConfigId == this.FlowConfigId && t.Code == "Start")
                .First();

            if (firstNode == null) throw new Exception("流程配置未设置起始节点");

            var start = InitFlowNodes();
            this.CurrentNodeId = start.Id;
            this.CurrentApproverIds = start.ApproverIds;

            var flowAction = ServiceLocator.GetByName<IAutofacFlowAction>(this.FlowAction);
            flowAction.Start(this, start);
        }

        public FlowNode InitFlowNodes()
        {
            var db = AppSession.CurrentDb.Value;
            var configNodes = db.Queryable<FlowConfigNode>().Where((t) => t.FlowConfigId == this.FlowConfigId).ToList();
            var nodes = new List<FlowNode>();

            foreach (var configNode in configNodes)
            {
                var node = new FlowNode()
                {
                    Id = SnowFlakeSingle.Instance.NextId().ToString(),
                    FlowId = this.Id,
                    ConfigNodeId = configNode.Id,
                    Name = configNode.Name,
                    Code = configNode.Code,
                    PreNodeCodes = configNode.PreNodeCodes,
                    RejectNodeCode = configNode.RejectNodeCode,
                    CandidateMode = configNode.CandidateMode,
                    PreUserIds = configNode.PreUserIds,
                    RoleIds = configNode.RoleIds,
                    DepartmentIds = configNode.DepartmentIds,
                    ApproverIds = new List<string>(),
                };

                if(node.Code == "Start") node.ApproverIds = new List<string>() { AppSession.CurrentUser.Value.Id };
                nodes.Add(node);
            }

            db.Add(nodes);

            var start = nodes.Where((t) => t.FlowId == this.Id && t.Code == "Start").First();
            return start;
        }




        public override void OnPreUpdate()
        {
            base.OnPreUpdate();
            if (this.CurrentNodeCode == "End")
            {
                this.IsEnd = true; // 如果当前节点是End，则标记为完成
            }
        }


        public override void OnPreDelete()
        {
            base.OnPreDelete();

            if (this.IsEnd) throw new Exception("流程已完成，无法撤销");

            //删除子节点
            var db = AppSession.CurrentDb.Value;
            db.Deleteable<FlowNode>().Where((t) => t.FlowId == this.Id).ExecuteCommand();
        }
    }
}
